package com.ffcs.cn.action.map.layersetting;

import com.ffcs.cn.DevelopProperties;
import com.ffcs.cn.action.common.StyleSettingPaneLine;
import com.ffcs.cn.action.common.StyleSettingPanelManager;
import com.ffcs.cn.action.common.StyleSettingPanelPoint;
import com.ffcs.cn.action.common.StyleSettingPanelRegion;
import com.supermap.data.Dataset;
import com.supermap.data.GeoStyle;
import com.supermap.data.Size2D;
import com.supermap.data.SymbolType;
import com.supermap.desktop.controls.ui.UICommonToolkit;
import com.supermap.desktop.controls.ui.controls.DialogResult;
import com.supermap.desktop.controls.ui.controls.SmDialog;
import com.supermap.desktop.controls.ui.controls.datasetChoose.DatasetChooseMode;
import com.supermap.desktop.controls.ui.controls.datasetChoose.SmDatasetChooser;
import com.supermap.desktop.controls.ui.controls.scrollPanel.SmNoBorderScrollPanel;
import com.supermap.desktop.controls.utilities.ComponentFactory;
import com.supermap.desktop.controls.utilities.MapViewUIUtilities;
import com.supermap.desktop.core.Application;
import com.supermap.desktop.core.Interface.IForm;
import com.supermap.desktop.core.Interface.IFormMap;
import com.supermap.desktop.core.enums.WindowType;
import com.supermap.desktop.core.event.colorSelect.IColorChangedListener;
import com.supermap.desktop.core.ui.controls.GridBagConstraintsHelper;
import com.supermap.desktop.core.utilties.DatasetTypeUtilities;
import com.supermap.desktop.core.utilties.FormUtilities;
import com.supermap.desktop.core.utilties.StringUtilities;
import com.supermap.desktop.core.utilties.SymbolTypeUtilities;
import com.supermap.mapping.*;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 图层管理器对话框
 *
  */
public class DialogLayerSettingMap extends SmDialog {
	private static final String PREFIX_SCALE = "1 : ";
	private static final int MAX_NUMBER_SCALE = 16; // 最大小数位数
	private StyleSettingPanelManager styleSettingPanelManager;
	/**
	 * 图层树
	 **/
	private LayerTree layerTree;
	private SmNoBorderScrollPanel scrollPanel;

	private JToolBar toolBar;
	private JButton buttonSelectAll;
	private JButton buttonSelectInvert;
	private JButton buttonDelete;
	private JButton buttonAdd;
	/**
	 * 是否可显示
	 **/
	private JCheckBox checkboxDisplayable;
	/**
	 * 是否可编辑
	 **/
	private JCheckBox checkBoxEditable;
	/**
	 * 是否可选择
	 **/
	private JCheckBox checkBoxSelectable;
	/**
	 * 是否可捕捉
	 **/
	@SuppressWarnings("SpellCheckingInspection")
	private JCheckBox checkBoxSnappable;

	/**
	 * 图层名
	 **/
	private JLabel labelLayerName;
	private JTextField textFieldLayerName;

	/**
	 * 最大可见比例尺
	 **/
	private JLabel labelMaxVisibleScale;
	private JComboBox<Object> comboBoxMaxVisibleScale;
	/**
	 * 最小可见比例尺
	 **/
	private JLabel labelMinVisibleScale;
	private JComboBox<Object> comboBoxMinVisibleScale;


	/**
	 * 填充类型的风格面板
	 */
	private final StyleSettingPanelRegion styleSettingPanelRegion = new StyleSettingPanelRegion() {
		@Override
		public IColorChangedListener getForceColorChangedListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					if (selectedLayer.getAdditionalSetting() instanceof LayerSettingVector && ((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle().getFillForeColor() != e.getColor()) {
						((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle().setFillForeColor(e.getColor());
					}
				}
				refresh();
			};
		}

		@Override
		public IColorChangedListener getBackgroundColorChangedListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					if (selectedLayer.getAdditionalSetting() instanceof LayerSettingVector && ((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle().getFillBackColor() != e.getColor()) {
						((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle().setFillBackColor(e.getColor());
					}
				}
				refresh();
			};
		}

		@Override
		public ChangeListener getOpaqueChangeListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					selectedLayer.setOpaqueRate(Integer.parseInt(spinnerOpaque.getValue().toString()));
				}
				refresh();
			};
		}

		@Override
		public void itemChange() {
			if (layerTree.getSelectedLayers().length != 1) {
				buttonBackgroundColor.setEnabled(false);
				buttonForceColor.setEnabled(false);
				spinnerOpaque.setEnabled(false);
				spinnerOpaque.setEnabled(false);
				return;
			}
			Layer layer = layerTree.getSelectedLayers()[0];
			if (layer.getAdditionalSetting().getType() == LayerSettingType.VECTOR) {
				LayerSettingVector layerSettingVector = (LayerSettingVector) layer.getAdditionalSetting();
				buttonForceColor.setColor(layerSettingVector.getStyle().getFillForeColor());
				buttonBackgroundColor.setColor(layerSettingVector.getStyle().getFillBackColor());
				spinnerOpaque.setValue(layer.getOpaqueRate());
				buttonBackgroundColor.setEnabled(true);
				buttonForceColor.setEnabled(true);
				spinnerOpaque.setEnabled(true);
			} else {
				buttonBackgroundColor.setEnabled(false);
				buttonForceColor.setEnabled(false);
				spinnerOpaque.setEnabled(false);
				spinnerOpaque.setEnabled(false);
			}
		}
	};

	/**
	 * 二维线类型的风格面板
	 */
	private final StyleSettingPaneLine styleSettingPaneLine = new StyleSettingPaneLine() {
		@Override
		public IColorChangedListener getLineColorChangedListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					if (selectedLayer.getAdditionalSetting() instanceof LayerSettingVector && ((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle().getFillForeColor() != e.getColor()) {
						((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle().setLineColor(e.getColor());
					}
				}
				refresh();
			};
		}

		@Override
		public ChangeListener getLineWidthChangeListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					if (selectedLayer.getAdditionalSetting() instanceof LayerSettingVector) {
						((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle().setLineWidth((double) spinnerLineWidth.getValue());
					}
				}
				refresh();
			};
		}

		@Override
		public void itemChange() {
			if (layerTree.getSelectedLayers().length != 1) {
				buttonLineColor.setEnabled(false);
				spinnerLineWidth.setEnabled(false);
				return;
			}
			Layer layer = layerTree.getSelectedLayers()[0];
			if (layer.getAdditionalSetting().getType() == LayerSettingType.VECTOR) {
				LayerSettingVector layerSettingVector = (LayerSettingVector) layer.getAdditionalSetting();
				buttonLineColor.setColor(layerSettingVector.getStyle().getLineColor());
				spinnerLineWidth.setValue(layerSettingVector.getStyle().getLineWidth());
				buttonLineColor.setEnabled(true);
				spinnerLineWidth.setEnabled(true);
			} else {
				buttonLineColor.setEnabled(false);
				spinnerLineWidth.setEnabled(false);
			}
		}
	};

	/**
	 * 点类型的风格面板
	 */
	private final StyleSettingPanelPoint styleSettingPanelPoint = new StyleSettingPanelPoint() {
		@Override
		public IColorChangedListener getSymbolColorChangeListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					if (selectedLayer.getAdditionalSetting() instanceof LayerSettingVector) {
						GeoStyle style = ((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle();
						style.setLineColor(e.getColor());
					}
				}
				refresh();
			};
		}

		@Override
		public ChangeListener getHeightChangeListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					if (selectedLayer.getAdditionalSetting() instanceof LayerSettingVector) {
						GeoStyle style = ((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle();
						style.setMarkerSize(new Size2D(style.getMarkerSize().getWidth(), (double) spinnerHeight.getValue()));
					}
				}
				refresh();
			};
		}

		@Override
		public ChangeListener getWidthChangeListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					if (selectedLayer.getAdditionalSetting() instanceof LayerSettingVector) {
						GeoStyle style = ((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle();
						style.setMarkerSize(new Size2D((double) spinnerWidth.getValue(), style.getMarkerSize().getHeight()));
					}
				}
				refresh();
			};
		}

		@Override
		public ChangeListener getMarkerAngleChangeListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					if (selectedLayer.getAdditionalSetting() instanceof LayerSettingVector) {
						GeoStyle style = ((LayerSettingVector) selectedLayer.getAdditionalSetting()).getStyle();
						style.setMarkerAngle(((double) spinnerMarkerAngle.getValue()));
					}
				}
				refresh();
			};
		}

		@Override
		public ChangeListener getAlphaChangeListener() {
			return e -> {
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					selectedLayer.setOpaqueRate(((int) spinnerOpaqueRate.getValue()));
				}
				refresh();
			};
		}

		@Override
		public void itemChange() {
			if (layerTree.getSelectedLayers().length != 1) {
				buttonSymbolColor.setEnabled(false);
				spinnerWidth.setEnabled(false);
				spinnerHeight.setEnabled(false);
				spinnerOpaqueRate.setEnabled(false);
				spinnerMarkerAngle.setEnabled(false);
				return;
			}
			Layer layer = layerTree.getSelectedLayers()[0];
			if (layer.getAdditionalSetting().getType() == LayerSettingType.VECTOR) {
				LayerSettingVector layerSettingVector = (LayerSettingVector) layer.getAdditionalSetting();
				buttonSymbolColor.setColor(layerSettingVector.getStyle().getLineColor());
				spinnerWidth.setValue(layerSettingVector.getStyle().getMarkerSize().getWidth());
				spinnerHeight.setValue(layerSettingVector.getStyle().getMarkerSize().getHeight());
				spinnerOpaqueRate.setValue(layer.getOpaqueRate());
				spinnerMarkerAngle.setValue(layerSettingVector.getStyle().getMarkerAngle());
				buttonSymbolColor.setEnabled(true);
				spinnerWidth.setEnabled(true);
				spinnerHeight.setEnabled(true);
				spinnerOpaqueRate.setEnabled(true);
				spinnerMarkerAngle.setEnabled(true);
			} else {
				buttonSymbolColor.setEnabled(false);
				spinnerWidth.setEnabled(false);
				spinnerHeight.setEnabled(false);
				spinnerOpaqueRate.setEnabled(false);
				spinnerMarkerAngle.setEnabled(false);
			}
		}
	};

	/**
	 * 固定比例尺枚举
	 */
	private enum DefaultScale {
		SCALE_5000(new ScaleModel("1 : 5000", 5000)),
		SCALE_25000(new ScaleModel("1 : 25000", 10000)),
		SCALE_50000(new ScaleModel("1 : 50000", 50000)),
		SCALE_100000(new ScaleModel("1 : 100000", 100000)),
		SCALE_500000(new ScaleModel("1 : 500000", 500000)),
		SCALE_10000000(new ScaleModel("1 : 1000000", 1000000)),
		SCALE_CURRENT(new ScaleModel(DevelopProperties.getString("String_CurrentScale"), 0));
		private final ScaleModel scaleModel;

		DefaultScale(ScaleModel scaleModel) {
			this.scaleModel = scaleModel;
		}

		public ScaleModel getScaleModel() {
			return scaleModel;
		}
	}

	/**
	 * 比例尺类型，最大或是最小
	 */
	public enum ScaleType {
		MAX, MIN
	}

	/**
	 * 最大和最小比例尺下拉列表栏输入改变时的监听
	 */
	private final ItemListener scaleChangeListener = new ItemListener() {
		/**
		 * 值改变时触发的函数
		 * 该方法的作用是刷新下拉列表文本框内的值以及返回将会被设置到图层最大或最小可显示比例尺的值
		 *
		 * @param scaleType 最大还是最小比例尺
		 * @return 返回将会设置到该图层的值
		 */
		private double scaleChange(ScaleType scaleType) {
			JComboBox<Object> temp;
			if (scaleType == ScaleType.MAX) {
				temp = comboBoxMaxVisibleScale;
			} else {
				temp = comboBoxMinVisibleScale;
			}
			Object selectedItem = temp.getSelectedItem();
			double targetScale = 0;
			// 输入的是数字
			if (selectedItem instanceof String) {
				// 正整数或正小数情况
				if (StringUtilities.isPositiveInteger(selectedItem.toString())
						|| StringUtilities.isPositiveDecimal(selectedItem.toString())) {
					// 确保不丢失精度
					BigDecimal bigDecimal = new BigDecimal(selectedItem.toString());
					targetScale = bigDecimal.doubleValue();
					if (targetScale > 1) {
						temp.setSelectedItem(new ScaleModel(PREFIX_SCALE + bigDecimal.stripTrailingZeros().toPlainString(), targetScale));
					}
				} else {
					// 非法字符串情况
					temp.setSelectedItem(new ScaleModel("0", ((IFormMap) Application.getActiveApplication().getActiveForm()).getMapControl().getMap().getScale()));
				}
			} else if (selectedItem instanceof ScaleModel) {
				// 若是选中的comboBox里面的内容
				targetScale = ((ScaleModel) selectedItem).getScale();
				if (targetScale > 1) {
					// 真实的比例尺应该用1 ÷ 比例尺大小
					targetScale = new BigDecimal(1).divide(new BigDecimal(targetScale), MAX_NUMBER_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();
				} else {
					targetScale = 0;
				}
				// 若选中的是当前比例尺范围, comboBox的值应该显示为'当前比例尺范围'的值而不是这个文本
				// 此时需要对comboBox内的值进行改变
				if ((selectedItem).toString().equals(DevelopProperties.getString("String_CurrentScale"))
						&& layerTree.getSelectedLayers().length == 1
						&& Application.getActiveApplication().getActiveForm() instanceof IFormMap) {
					double currentScale = ((IFormMap) Application.getActiveApplication().getActiveForm()).getMapControl().getMap().getScale();
					temp.setSelectedItem(new ScaleModel(PREFIX_SCALE + new BigDecimal(1 / currentScale).stripTrailingZeros().toPlainString(), targetScale));
				}
			} else {
				// 其他
				temp.setSelectedItem(new ScaleModel("0", targetScale));
			}
			return targetScale;
		}

		@Override
		public void itemStateChanged(ItemEvent e) {
			if (e.getSource() == comboBoxMaxVisibleScale) {
				double scale = scaleChange(ScaleType.MAX);
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					selectedLayer.setMaxVisibleScale(scale);
				}
				refresh();
			} else if (e.getSource() == comboBoxMinVisibleScale) {
				double scale = scaleChange(ScaleType.MIN);
				for (Layer selectedLayer : layerTree.getSelectedLayers()) {
					selectedLayer.setMinVisibleScale(scale);
				}
				refresh();
			}
		}
	};

	/**
	 * 比例尺数据模型
	 * comboBox通过设置此数据模型对比例尺数据进行更改
	 * 比例尺大小，注意是分母部分，例如 1/100，这里比例尺大小的值是100
	 */
	private static class ScaleModel {
		/**
		 * 显示的文本
		 **/
		private final String tip;
		/**
		 * 比例尺大小
		 **/
		private double scale;

		public ScaleModel(String tip, double scale) {
			this.scale = scale;
			this.tip = tip;
		}

		public double getScale() {
			return scale;
		}

		public void setScale(double scale) {
			this.scale = scale;
		}

		@Override
		public String toString() {
			return tip;
		}
	}

	public DialogLayerSettingMap() {
		this.setMinimumSize(new Dimension(800, 520));
		this.setTitle(DevelopProperties.getString("String_LayerSetting"));
		initComponents();
		initLayout();
		registerEvents();
		initState();
	}

	private void initComponents() {
		layerTree = new LayerTree();
		scrollPanel = new SmNoBorderScrollPanel(layerTree);

		buttonSelectAll = ComponentFactory.createToolBarButtonSelectAll();
		buttonSelectInvert = ComponentFactory.createToolBarButtonSelectInverse();
		buttonAdd = ComponentFactory.createToolBarButtonAddData();
		buttonDelete = ComponentFactory.createToolBarButtonDelete();

		toolBar = new JToolBar();
		toolBar.add(buttonAdd);
		toolBar.add(buttonDelete);
		toolBar.addSeparator();
		toolBar.add(buttonSelectAll);
		toolBar.add(buttonSelectInvert);
		toolBar.setFloatable(false);


		checkBoxSnappable = new JCheckBox(DevelopProperties.getString("String_Snappable"));
		checkboxDisplayable = new JCheckBox(DevelopProperties.getString("String_Displayable"));
		checkBoxEditable = new JCheckBox(DevelopProperties.getString("String_Editable"));
		checkBoxSelectable = new JCheckBox(DevelopProperties.getString("String_Selectable"));
		labelLayerName = new JLabel(DevelopProperties.getString("String_Label_LayerName"));
		textFieldLayerName = new JTextField();
		labelMaxVisibleScale = new JLabel(DevelopProperties.getString("String_Label_MaxScale"));
		comboBoxMaxVisibleScale = new JComboBox<>();
		comboBoxMaxVisibleScale.setEditable(true);
		labelMinVisibleScale = new JLabel(DevelopProperties.getString("String_Label_MinScale"));
		comboBoxMinVisibleScale = new JComboBox<>();
		comboBoxMinVisibleScale.setEditable(true);

		// 初始化最大最小比例尺固定下拉列表
		for (DefaultScale value : DefaultScale.values()) {
			comboBoxMaxVisibleScale.addItem(value.getScaleModel());
			comboBoxMinVisibleScale.addItem(value.getScaleModel());
		}
	}

	private void initLayout() {
		this.setLayout(new GridBagLayout());
		// 左边的图层树面板
		JPanel treePanel = new JPanel();
		treePanel.setBorder(BorderFactory.createTitledBorder(DevelopProperties.getString("String_Layer")));
		treePanel.setLayout(new GridBagLayout());
		treePanel.add(scrollPanel, new GridBagConstraintsHelper(0, 0, 1, 1)
				.setWeight(1, 1)
				.setFill(GridBagConstraints.BOTH));
		treePanel.setPreferredSize(new Dimension(200, 300));
		treePanel.setMinimumSize(new Dimension(200, 200));
		// 右边的设置面板
		JPanel settingPanel = new JPanel();
		settingPanel.setLayout(new GridBagLayout());

		JPanel baseSettingPanel = new JPanel();
		baseSettingPanel.setLayout(new GridBagLayout());
		baseSettingPanel.setBorder(BorderFactory.createTitledBorder(DevelopProperties.getString("String_BaseSetting")));

		JPanel checkBoxPanel = new JPanel();
		checkBoxPanel.setLayout(new GridBagLayout());
		checkBoxPanel.add(checkboxDisplayable, new GridBagConstraintsHelper(0, 0, 1, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.NONE)
				.setWeight(1, 0));
		checkBoxPanel.add(checkBoxSelectable, new GridBagConstraintsHelper(1, 0, 1, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.NONE)
				.setWeight(1, 0));
		checkBoxPanel.add(checkBoxEditable, new GridBagConstraintsHelper(2, 0, 1, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.NONE)
				.setWeight(1, 0));
		checkBoxPanel.add(checkBoxSnappable, new GridBagConstraintsHelper(3, 0, 1, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.NONE)
				.setWeight(1, 0));
		baseSettingPanel.add(checkBoxPanel, new GridBagConstraintsHelper(0, 0, 3, 1)
				.setAnchor(GridBagConstraints.CENTER)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
				.setFill(GridBagConstraints.HORIZONTAL)
				.setWeight(1, 0));
		baseSettingPanel.add(labelLayerName, new GridBagConstraintsHelper(0, 1, 1, 1)
				.setAnchor(GridBagConstraints.WEST)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
				.setFill(GridBagConstraints.NONE)
				.setWeight(0, 0));
		baseSettingPanel.add(textFieldLayerName, new GridBagConstraintsHelper(1, 1, 2, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.HORIZONTAL)
				.setWeight(1, 0));
		baseSettingPanel.add(labelMaxVisibleScale, new GridBagConstraintsHelper(0, 2, 1, 1)
				.setAnchor(GridBagConstraints.WEST)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
				.setFill(GridBagConstraints.NONE)
				.setWeight(0, 0));
		baseSettingPanel.add(comboBoxMaxVisibleScale, new GridBagConstraintsHelper(1, 2, 2, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.HORIZONTAL)
				.setWeight(1, 0));
		baseSettingPanel.add(labelMinVisibleScale, new GridBagConstraintsHelper(0, 3, 1, 1)
				.setAnchor(GridBagConstraints.WEST)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
				.setFill(GridBagConstraints.NONE)
				.setWeight(0, 0));
		baseSettingPanel.add(comboBoxMinVisibleScale, new GridBagConstraintsHelper(1, 3, 2, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.HORIZONTAL)
				.setWeight(1, 0));
		settingPanel.add(baseSettingPanel, new GridBagConstraintsHelper(0, 1, 1, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.HORIZONTAL)
				.setWeight(1, 0));
		settingPanel.add(styleSettingPanelRegion, new GridBagConstraintsHelper(0, 2, 1, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.HORIZONTAL)
				.setWeight(1, 0));
		settingPanel.add(styleSettingPaneLine, new GridBagConstraintsHelper(0, 3, 1, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.HORIZONTAL)
				.setWeight(1, 0));
		settingPanel.add(styleSettingPanelPoint, new GridBagConstraintsHelper(0, 4, 1, 1)
				.setInsets(GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.CONTROLS_GAP)
				.setAnchor(GridBagConstraints.WEST)
				.setFill(GridBagConstraints.HORIZONTAL)
				.setWeight(1, 0));
		settingPanel.add(new JPanel(), new GridBagConstraintsHelper(0, 10, 1, 1)
				.setFill(GridBagConstraints.BOTH)
				.setWeight(1, 1));

		// toolbar添加到总布局
		this.add(toolBar, new GridBagConstraintsHelper(0, 0, 2, 1)
				.setWeight(1, 0)
				.setAnchor(GridBagConstraints.WEST)
				.setInsets(GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.CONTROLS_GAP, 0, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
				.setFill(GridBagConstraints.HORIZONTAL));

		// 图层树面板和设置面板添加到总布局中
		this.add(treePanel, new GridBagConstraintsHelper(0, 1, 1, 1)
				.setWeight(0, 1)
				.setInsets(GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
				.setFill(GridBagConstraints.VERTICAL));
		this.add(settingPanel, new GridBagConstraintsHelper(1, 1, 1, 1)
				.setWeight(1, 1)
				.setInsets(GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.CONTROLS_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP, GridBagConstraintsHelper.FRAME_CONTROL_GAP)
				.setFill(GridBagConstraints.BOTH));

	}

	private void initState() {
		// -----初始化图层树----- //
		IForm form = Application.getActiveApplication().getActiveForm();
		if (form instanceof IFormMap) {
			// 获取当前地图窗口所有图层
			Layers layers = ((IFormMap) form).getMapControl().getMap().getLayers();
			for (int i = 0; i < layers.getCount(); i++) {
				// 遍历所有图层，依次添加进图层树
				layerTree.addLayer(layers.get(i));
			}
		}
		checkboxDisplayable.setEnabled(false);
		checkBoxSelectable.setEnabled(false);
		checkBoxEditable.setEnabled(false);
		checkBoxSnappable.setEnabled(false);
		textFieldLayerName.setEnabled(false);
		textFieldLayerName.setText("");
		comboBoxMaxVisibleScale.setEnabled(false);
		comboBoxMaxVisibleScale.setSelectedItem(new ScaleModel("0", 0));
		comboBoxMinVisibleScale.setEnabled(false);
		comboBoxMinVisibleScale.setSelectedItem(new ScaleModel("0", 0));
		styleSettingPanelManager = new StyleSettingPanelManager();
		// 默认情况下，使用点对象风格的面板
		styleSettingPanelManager.add(styleSettingPanelPoint);
		styleSettingPanelManager.add(styleSettingPaneLine);
		styleSettingPanelManager.add(styleSettingPanelRegion);
		styleSettingPanelManager.setActivePanel(styleSettingPanelPoint);
		styleSettingPanelManager.getActivePanel().itemChange();
		// 如果有节点，则选中第一个节点
		layerTree.setSelectedLayer(0);
	}

	private void registerEvents() {
		layerTree.getModel().addTreeModelListener(new TreeModelListener() {
			@Override
			public void treeNodesChanged(TreeModelEvent e) {

			}

			@Override
			public void treeNodesInserted(TreeModelEvent e) {
				buttonDelete.setEnabled(layerTree.getLayerCount() != 0);
				buttonSelectAll.setEnabled(layerTree.getLayerCount() != 0);
			}

			@Override
			public void treeNodesRemoved(TreeModelEvent e) {
				buttonDelete.setEnabled(layerTree.getLayerCount() != 0);
				buttonSelectAll.setEnabled(layerTree.getLayerCount() != 0);
			}

			@Override
			public void treeStructureChanged(TreeModelEvent e) {

			}
		});
		// 图层管理树选择树节点的监听，点击图层节点，设置面板的参数
		layerTree.addTreeSelectionListener(e -> {
			// 判断应该显示哪个风格设置控件
			if (layerTree.getSelectedLayers().length == 1 && SymbolTypeUtilities.getSymbolType(layerTree.getSelectedLayers()[0].getDataset().getType()) == SymbolType.FILL) {
				styleSettingPanelManager.setActivePanel(styleSettingPanelRegion);
			} else if (layerTree.getSelectedLayers().length == 1 && SymbolTypeUtilities.getSymbolType(layerTree.getSelectedLayers()[0].getDataset().getType()) == SymbolType.LINE) {
				styleSettingPanelManager.setActivePanel(styleSettingPaneLine);
			} else {
				styleSettingPanelManager.setActivePanel(styleSettingPanelPoint);
			}
			styleSettingPanelManager.getActivePanel().itemChange();
			if (layerTree.getSelectedLayers().length == 1) {
				// 选中一个图层
				Layer layer = layerTree.getSelectedLayers()[0];
				checkBoxSnappable.setSelected(layer.isSnapable());
				checkBoxEditable.setSelected(layer.isEditable());
				checkBoxSelectable.setSelected(layer.isSelectable());
				checkboxDisplayable.setSelected(layer.isVisible());
				textFieldLayerName.setEnabled(true);
				checkBoxSnappable.setEnabled(true);
				checkBoxEditable.setEnabled(true);
				checkBoxSelectable.setEnabled(true);
				checkboxDisplayable.setEnabled(true);
				textFieldLayerName.setText(layer.getCaption());
				comboBoxMaxVisibleScale.setSelectedItem(new ScaleModel("0", layer.getMaxVisibleScale()));
				comboBoxMinVisibleScale.setSelectedItem(new ScaleModel("0", layer.getMinVisibleScale()));
				comboBoxMaxVisibleScale.setEnabled(true);
				comboBoxMinVisibleScale.setEnabled(true);
			} else {
				// 选中多个图层
				checkboxDisplayable.setEnabled(false);
				checkBoxSelectable.setEnabled(false);
				checkBoxEditable.setEnabled(false);
				checkBoxSnappable.setEnabled(false);
				textFieldLayerName.setEnabled(false);
				textFieldLayerName.setText("");
				comboBoxMaxVisibleScale.setEnabled(false);
				comboBoxMaxVisibleScale.setSelectedItem(new ScaleModel("0", 0));
				comboBoxMinVisibleScale.setEnabled(false);
				comboBoxMinVisibleScale.setSelectedItem(new ScaleModel("0", 0));
			}
		});

		// 添加按钮，将选择的数据集添加进当前地图里同时也添加进图层树
		buttonAdd.addActionListener(e -> {
			SmDatasetChooser smDatasetChooser = new SmDatasetChooser(DatasetChooseMode.DATASET);
			smDatasetChooser.setSupportDatasetTypes(DatasetTypeUtilities.getDatasetTypeVectorWithoutTabular());
			if (smDatasetChooser.showDialog() == DialogResult.OK) {
				List<Object> selectedObjects = smDatasetChooser.getSelectedObjects();
				// 如果当前窗口不是地图窗口就打开一个空白地图窗口并将选择的数据集添加进地图
				if (!(Application.getActiveApplication().getActiveForm() instanceof IFormMap)) {
					FormUtilities.fireNewWindowEvent(WindowType.MAP);
				}
				for (Object obj : selectedObjects) {
					if (obj instanceof Dataset) {
						Map map = ((IFormMap) Application.getActiveApplication().getActiveForm()).getMapControl().getMap();
						Layer[] layer = MapViewUIUtilities.addDatasetsToMap(map, map.getLayers().getCount(), (Dataset) obj);
						layerTree.addLayer(layer[0]);
					}
				}
				// 添加完成后，选中最后一个节点
				layerTree.setSelectedLayer(layerTree.getLayerCount() - 1);
			}
			smDatasetChooser.dispose();
		});
		// 删除按钮
		buttonDelete.addActionListener(e -> layerTree.removeSelectedLayers());
		// 全选按钮
		buttonSelectAll.addActionListener(e -> {
			int[] indices = new int[layerTree.getLayerCount()];
			for (int i = 0; i < layerTree.getLayerCount(); i++) {
				indices[i] = i;
			}
			layerTree.setSelectedLayer(indices);
		});
		// 反选按钮
		buttonSelectInvert.addActionListener(e -> {
			Layer[] layers = layerTree.getAllLayers();
			List<Layer> selectedLayer = Arrays.asList(layerTree.getSelectedLayers());
			List<Integer> toRemoveSelectedLayer = new ArrayList<>();
			List<Integer> toSelectedLayer = new ArrayList<>();
			for (Layer layer : layers) {
				if (selectedLayer.contains(layer)) {
					toRemoveSelectedLayer.add(layerTree.getLayerIndex(layer));
				} else {
					toSelectedLayer.add(layerTree.getLayerIndex(layer));
				}
			}
			layerTree.setSelectedLayer(Arrays.stream(toSelectedLayer.toArray(new Integer[0])).mapToInt(Integer::valueOf).toArray());
			layerTree.removeSelectedLayer(Arrays.stream(toRemoveSelectedLayer.toArray(new Integer[0])).mapToInt(Integer::valueOf).toArray());
		});

		// 图层是否可显示
		checkboxDisplayable.addItemListener(e -> {
			if (layerTree.getSelectedLayers().length == 1 && checkboxDisplayable.isEnabled()) {
				Layer selectedLayer = layerTree.getSelectedLayers()[0];
				selectedLayer.setVisible(checkboxDisplayable.isSelected());
				UICommonToolkit.getLayersManager().getLayersTree().updateUI();
				refresh();
				checkBoxSelectable.setEnabled(checkboxDisplayable.isSelected());
				checkBoxEditable.setEnabled(checkboxDisplayable.isSelected());
				checkBoxSnappable.setEnabled(checkboxDisplayable.isSelected());
			}
		});
		// 图层是否可选择
		checkBoxSelectable.addItemListener(e -> {
			if (layerTree.getSelectedLayers().length == 1 && checkBoxSelectable.isEnabled()) {
				Layer layer = layerTree.getSelectedLayers()[0];
				layer.setSelectable(checkBoxSelectable.isSelected());
				UICommonToolkit.getLayersManager().getLayersTree().updateUI();
				refresh();
			}
		});
		// 图层是否可编辑
		checkBoxEditable.addItemListener(e -> {
			if (layerTree.getSelectedLayers().length == 1 && checkBoxEditable.isEnabled()) {
				Layer layer = layerTree.getSelectedLayers()[0];
				layer.setEditable(checkBoxEditable.isSelected());
				UICommonToolkit.getLayersManager().getLayersTree().updateUI();
				refresh();
				// 若可编辑则一定必须是可选择的
				if (checkBoxEditable.isSelected()) {
					checkBoxSelectable.setSelected(true);
				}
			}
		});
		// 是否可捕捉
		checkBoxSnappable.addItemListener(e -> {
			if (layerTree.getSelectedLayers().length == 1 && checkBoxSnappable.isEnabled()) {
				Layer layer = layerTree.getSelectedLayers()[0];
				layer.setSnapable(checkBoxSnappable.isSelected());
				UICommonToolkit.getLayersManager().getLayersTree().updateUI();
				refresh();
			}
		});

		// 图层标题设置
		textFieldLayerName.getDocument().addDocumentListener(new DocumentListener() {
			/**
			 * 文本内容改变时，设置图层标题
			 */
			private void setText() {
				if (layerTree.getSelectedLayers().length == 1
						&& textFieldLayerName.getText() != null
						&& !textFieldLayerName.getText().equals("")
						&& layerTree.getSelectedLayers().length == 1) {
					layerTree.getSelectedLayers()[0].setCaption(textFieldLayerName.getText());
					// 更新图层树的显示
					SwingUtilities.invokeLater(() -> layerTree.updateUI());
				}
			}

			@Override
			public void insertUpdate(DocumentEvent e) {
				setText();
			}

			@Override
			public void removeUpdate(DocumentEvent e) {
				setText();
			}

			@Override
			public void changedUpdate(DocumentEvent e) {

			}
		});

		// 最大比例尺范围监听
		comboBoxMaxVisibleScale.addItemListener(scaleChangeListener);
		// 最小比例尺范围监听
		comboBoxMinVisibleScale.addItemListener(scaleChangeListener);

	}

	/**
	 * 刷新窗口
	 */
	private void refresh() {
		if (Application.getActiveApplication().getActiveForm() instanceof IFormMap) {
			((IFormMap) (Application.getActiveApplication().getActiveForm())).getMapControl().getMap().refresh();
		}
	}
}
